package com.prp.bo;

import java.util.ArrayList;
import java.util.Date;

import org.hibernate.Transaction;

import com.prp.algorithm.NeighboursRecommend;
import com.prp.algorithm.SubjectsRecommend;
import com.prp.algorithm.SubjectsRelatedRecommend;
import com.prp.db.DAOFactory;
import com.prp.db.HibernateSessionFactory;
import com.prp.db.idao.IArtificialNeighborRecommendationRecordDAO;
import com.prp.db.idao.IArtificialSubjectRecommendationRecordDAO;
import com.prp.db.po.ArtificialNeighborRecommendationRecord;
import com.prp.db.po.ArtificialSubjectRecommendationRecord;
import com.prp.db.po.RecommendationEntity;
import com.prp.db.po.SubjectCategory;
import com.prp.db.po.SubjectChildCategory;
import com.prp.db.po.SubjectRecommendation;

public class Recommendation {
	
	/**
	 * 添加人工主题推荐
	 * @param fromId
	 * @param toId
	 * @param recommendId
	 * @return -0 commit error, 1 commit OK
	 */
	public static int addArtificialSubjectRecommendation(int fromId, int toId, int subjectId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialSubjectRecommendationRecordDAO asrDao = factory.getArtificialSubjectRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			ArtificialSubjectRecommendationRecord asr = new ArtificialSubjectRecommendationRecord(fromId, toId, subjectId);
			asrDao.save(asr);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}
	
	/**
	 * 获取一个用户的人工主题推荐列表
	 * @param userId
	 * @return null if there is no recommendation for userId
	 */
	public static ArrayList<ArtificialSubjectRecommendationRecord> getArtificialSubjectRecommendationRecord(int userId) {
		ArrayList<ArtificialSubjectRecommendationRecord> asrList = new ArrayList<ArtificialSubjectRecommendationRecord>();
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialSubjectRecommendationRecordDAO asrDao = factory.getArtificialSubjectRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			asrList = (ArrayList<ArtificialSubjectRecommendationRecord>) asrDao.findByRecommToId(userId);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return asrList;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return asrList;
	}
	
	/**
	 * 获取一个用户的某一条人工主题推荐
	 * @param userId
	 * @param subjectRecommendationId
	 * @return null if no such recommendation
	 */
	public static ArtificialSubjectRecommendationRecord getArtificialSubjectRecommendationRecord(int userId, int subjectRecommendationId) {
		ArtificialSubjectRecommendationRecord result = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialSubjectRecommendationRecordDAO asrDao = factory.getArtificialSubjectRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (asrDao.findById(subjectRecommendationId) == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			result = asrDao.findById(subjectRecommendationId);
			if (result.getRecommToId() != userId) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
	
	/**
	 * 删除用户的某一主题帖推荐
	 * @param userId
	 * @param subjectRecommendationId
	 * @return -2 not a recommendation of this user, -1 recommendation not exist, 0 commit error, 1 commit OK
	 */
	public static int deleteArtificialSubjectRecommendationRecord(int userId, int subjectRecommendationId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialSubjectRecommendationRecordDAO asrDao = factory.getArtificialSubjectRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (asrDao.findById(subjectRecommendationId) == null) {
				HibernateSessionFactory.getSession().close();
				return -1;
			}
			ArtificialSubjectRecommendationRecord asr = asrDao.findById(subjectRecommendationId);
			if (asr.getRecommToId() != userId) {
				HibernateSessionFactory.getSession().close();
				return -2;
			}
			asrDao.delete(asr);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}
	
	/**
	 * 添加人工邻友推荐
	 * @param fromId
	 * @param toId
	 * @param recommentUserId
	 * @return 0 commit error, 1 commit OK
	 */
	public static int addArtificialNeighbourRecommendation(int fromId, int toId, int recommentUserId) {
		Date date = new Date();
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialNeighborRecommendationRecordDAO anrDao = factory.getArtificialNeighborRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			ArtificialNeighborRecommendationRecord anr = new ArtificialNeighborRecommendationRecord(fromId, toId, recommentUserId, date);
			anrDao.save(anr);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}
	
	/**
	 * 获取一个用户的人工邻友推荐列表
	 * @param userId
	 * @return null if there is no recommendation for userId
	 */
	public static ArrayList<ArtificialNeighborRecommendationRecord> getArtificialNeighbourRecommendation(int userId) {
		ArrayList<ArtificialNeighborRecommendationRecord> anrList = new ArrayList<ArtificialNeighborRecommendationRecord>();
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialNeighborRecommendationRecordDAO anrDao = factory.getArtificialNeighborRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			anrList = (ArrayList<ArtificialNeighborRecommendationRecord>) anrDao.findByInviteeId(userId);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return anrList;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return anrList;
	}
	
	/**
	 * 获取一个用户的某一条人工邻友推荐
	 * @param userId
	 * @param neighbourRecommendationId
	 * @return null if there is no such recommendation
	 */
	public static ArtificialNeighborRecommendationRecord getArtificialNeighbourRecommendationRecord(int userId, int neighbourRecommendationId) {
		ArtificialNeighborRecommendationRecord result = null;
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialNeighborRecommendationRecordDAO anrDao = factory.getArtificialNeighborRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (anrDao.findById(neighbourRecommendationId) == null) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			result = anrDao.findById(neighbourRecommendationId);
			if (result.getInviteeId() != userId) {
				HibernateSessionFactory.getSession().close();
				return null;
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return result;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return result;
	}
	
	/**
	 * 删除用户的某一邻友推荐
	 * @param userId
	 * @param neighbourRecommendationId
	 * @return -2 not a recommendation of this user, -1 recommendation not exist, 0 commit error, 1 commit OK
	 */
	public static int deleteArtificialNeighbourRecommendationRecord(int userId, int neighbourRecommendationId) {
		DAOFactory factory = DAOFactory.getDAOFactory();
		IArtificialNeighborRecommendationRecordDAO anrDao = factory.getArtificialNeighborRecommendationRecordDAO();
		Transaction tx = null;
		try {
			tx = HibernateSessionFactory.getSession().beginTransaction();
			if (anrDao.findById(neighbourRecommendationId) == null) {
				HibernateSessionFactory.getSession().close();
				return -1;
			}
			ArtificialNeighborRecommendationRecord anr = anrDao.findById(neighbourRecommendationId);
			if (anr.getInviteeId() != userId) {
				HibernateSessionFactory.getSession().close();
				return -2;
			}
			anrDao.delete(anr);
			tx.commit();
		} catch (Exception e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
			return 0;
		} finally {
			HibernateSessionFactory.getSession().close();
		}
		return 1;
	}


	/**
	 * 获取主题帖TOPN推荐
	 * @return
	 */
	public static ArrayList<SubjectRecommendation> getSubjectRecommendationRecommend(int topNum) {
		return SubjectsRecommend.getSubjectRecommendationRecommend(topNum);
	}
	
	/**
	 * 获取推荐实体TOPN推荐
	 * @return
	 */
	public static ArrayList<RecommendationEntity> getRecommendationEntityRecommend(int topNum) {
		return SubjectsRecommend.getRecommendationEntityRecommend(topNum);
	}
	
	/**
	 * 返回对用户userId的topNum主题贴推荐
	 * 
	 * @param topNum
	 * @param userId
	 * @return
	 */
	public static ArrayList<SubjectRecommendation> getSubjectRecommend(
			int topNum, int userId) {
		return SubjectsRelatedRecommend.getSubjectRecommend(topNum, userId);
	}
	
	/**
	 * 获取主题帖类别的TOPN推荐
	 * @return
	 */
	public static ArrayList<SubjectCategory> getSubjectCategoryRecommend(int topNum) {
		return SubjectsRecommend.getSubjectCategoryRecommend(topNum);
	}
	
	/**
	 * 获取主题帖子类别TOPN推荐
	 * @return
	 */
	public static ArrayList<SubjectChildCategory> getSubjectChildCategoryRecommend(int topNum) {
		return SubjectsRecommend.getSubjectChildCategoryRecommend(topNum);
	}
	
	/**
	 * 输入一个用户id，返回自动推荐的相关用户id的列表。
	 * 
	 * @param userId
	 * @return 对userId进行的邻友推荐结果，返回为相关用户id列表
	 */
	public static ArrayList<Integer> recommend(int userId) {
		return NeighboursRecommend.recommend(userId);
	}
	
}
